<!DOCTYPE html>
<html>

<head>
	<meta charset="UTF-8">
	<title>可输入的下拉框（允许输入非选项值）</title>
	<link rel="stylesheet" href="../../libs/layui/layui-2.4.5/dist/css/layui.css">
	<script src="../../libs//layui/layui-2.4.5/dist/layui.js"></script>
	<style>


	</style>
</head>

<body style="margin: 10px;">

	<form class="layui-form" action="" id="formWindow">
		<div class="layui-form-item">
			<label class="layui-form-label">姓名：</label>
			<div class="layui-input-inline">
				<input name="xm" class="layui-input" lay-verify="" placeholder="请输入姓名">
			</div>
		</div>

		<div class="layui-form-item">
			<label class="layui-form-label">救援列车</label>
			<div class="layui-input-block" style="width: 200px;">

				<!-- 用于编辑时回填信息-->
				<!-- <input id="jylc_default" type="hidden" value="${item.jylc}"> -->
				<select id="jylc" name="jylc" class="layui-input" lay-verify="required" placeholder="请输入救援列车"
					lay-search>
					<option value="">请选择</option>

					<option value="鹰潭机务段-1">鹰潭机务段-1</option>
					<option value="福州机务段-2">福州机务段-2</option>
					<option value="向塘机务段-3">向塘机务段-3</option>

				</select>
			</div>
		</div>

		<div class="layerBtnCenter btn-box btn-box-1">
			<button type="button" class="layui-btn" lay-filter="submitBtnAdd" lay-submit id="saveBtn"><i
					class="iconfont"></i>取值
			</button>
			<button type="button" class="layui-btn btn-close" type="reset" id="reset"><i class="iconfont"></i>重置
			</button>
		</div>
	</form>

	<div>
		<h1>-------------------------------------</h1>
		<span>原生下拉框</span>
		<select placeholder="请输入救援列车" lay-search>
			<option value="">请选择</option>

			<option value="鹰潭机务段">鹰潭机务段-1</option>
			<option value="福州机务段">福州机务段-2</option>
			<option value="向塘机务段">向塘机务段-3</option>

		</select>
	</div>


	<script>


		/**
		 * @note 可编辑下拉框
		 * @author jiangxu
		 */
		class EditableCombobox {

			constructor(layuiId, $) {

				this.layuiId = layuiId;
				this._$ = $;
				this.invaildTagNameOfDD = "id_" + this.layuiId + "_dd";
				this.invaildTagNameOfOption = "id_" + this.layuiId + "_option";

				this.invalidValue_DataKey = "data-" + this.layuiId;

				this.defaultValue4InvalidTag = "#"

				this.textObj = this._$(this._$("#" + this.layuiId).next()[0].children[0]);
				this.selectObj = this._$(this._$("#" + this.layuiId).next()[0].children[1]);

				this.defaultValueObj = this._$("#" + this.layuiId + "_default");

				this.init();

				this.putDefaultValue();

			}

			/**
			 * 用于编辑时回填信息
			 */
			putDefaultValue() {
				/**
				 * 处于编辑界面时，下拉框会被预填入值的。此时需要处理显示【非法值的问题】
				 * 在页面加载完毕时触发
				 */
				//获取实际值
				if (!this.defaultValueObj) {
					return;
				}
				var value_default = this.defaultValueObj.val();
				if (value_default == undefined || value_default == '' || value_default == null) {
					return;
				}
				//如果是已知的值，就忽略；如果不是，需要追加 非法信息
				var arrValue = this.getValidValues();
				if (arrValue.indexOf(value_default) >= 0) {
					return;
				}

				console.log(value_default, arrValue);
				this._$("#" + this.layuiId).val(value_default);
				this.textObj.find('input').val(value_default);


			}

			init() {

				// var inputStr = "";
				var that = this;

				this.textObj.on('keyup', function (v) {

					that.appendInfoTag4InvalidValue();

				});

				/**
				 * 对已有的下拉框值 提前绑定 click 事件。
				 * 如果点击了已有值，则需要提前清楚【非法值】
				 */
				this.selectObj.find("dd").on('click', function (v) {

					//清除预存 非法值
					that._$("#" + that.layuiId).data(that.invalidValue_DataKey, "");

					//清除非法值的 dom
					// console.log($("#"+layuiId).data("jylc-data"));
					// console.log($(this).html())
					// 删除之前的 非法的option 的dom
					if (that._$("#" + that.invaildTagNameOfOption)) {
						that._$("#" + that.invaildTagNameOfOption).remove();
						that._$("#" + that.invaildTagNameOfDD).remove();
					}

				});



			}

			/**
			 * 获取有效值集合
			 */
			getValidValues() {
				var values = [];
				var that = this;
				this._$("#" + this.layuiId).find("option").each(function (index) {
					// console.log(that._$(this));
					var v = that._$(this).attr("value");
					if (v != undefined && v != null && v != '') {
						values.push(v);
					}
				})

				return values;
			}

			/**
			 * 根据【非法值】追加标签信息
			 */
			appendInfoTag4InvalidValue() {

				var inputStr = this.textObj.find('input').val();

				this._$("#" + this.layuiId).data(this.invalidValue_DataKey, inputStr);

				// 删除之前的 非法的option 的dom
				if (this._$("#" + this.invaildTagNameOfOption)) {
					this._$("#" + this.invaildTagNameOfOption).remove();
					this._$("#" + this.invaildTagNameOfDD).remove();
				}
				this._$("#" + this.layuiId).append('<option id="' + this.invaildTagNameOfOption + '" value="' + this.defaultValue4InvalidTag + '" selected>' + inputStr + '</option>')

				//先移除内部的 class="layui-this"
				this.selectObj.find(".layui-this").removeClass("layui-this");

				this.selectObj.append('<dd id="' + this.invaildTagNameOfDD + '" class="layui-this" lay-value="' + this.defaultValue4InvalidTag + '" >' + inputStr + '（未定义）</dd>');

				this.textObj.val(this.defaultValue4InvalidTag);

			}

			getValue() {
				var name = this._$("#" + this.layuiId).attr('name');
				var value = this._$("#" + this.layuiId).val();
				if (value == this.defaultValue4InvalidTag) {
					value = this._$("#" + this.layuiId).data(this.invalidValue_DataKey);
				}
				// var formData = {};
				// formData[name] = value;
				return value;
			}
		}






		layui.use(['jquery', 'layer', 'form', 'table', 'laydate', 'util', 'upload', 'element'], function () {
			var $ = layui.jquery;
			var layer = layui.layer;
			var form = layui.form;
			var laydate = layui.laydate;
			var element = layui.element;
			var table = layui.table;
			var util = layui.util;
			var layerWindow;
			var upload = layui.upload;


			var serializeFormToObject = function (formSelector) {

				var formData = {};
				formSelector.find(':input[name]').each(function () {
					var name = $(this).attr('name');
					var value = $(this).val();
					if ($(this).is('select')) {
						value = $(this).find('option:selected').val();
					}

					formData[name] = value;
				});

				// var jsonData = JSON.stringify(formData);
				return formData;
			};

			var jxCombobox = new EditableCombobox("jylc", $);
			// jxCombobox.init()


			form.on('submit(submitBtnAdd)', function (data) {
				var datas = data.field;

				var dataString = JSON.stringify(datas);
				console.log(dataString);

				// var ds = serializeFormToObject($("#formWindow"));
				// console.log(JSON.stringify(ds));

				console.log(jxCombobox.getValue());


			});



			// $("#reset").click(() => {
			// 	// debugger
			// 	var t = $($("#"+layuiId).next()[0].children[0]).find(":input");
			// 	var v = t.val();

			// 	setTimeout(function () {
			// 		t.val(v);
			// 	}, 100)

			// })



		});





	</script>





</body>

</html>